package twi.result.graph;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;

import com.hp.hpl.jena.graph.Node;
import com.hp.hpl.jena.ontology.OntProperty;
import com.hp.hpl.jena.rdf.model.RDFNode;

import twi.OWLModel;
import twi.filter.NodeFilter;
import twi.result.table.RTable;

public class GraphFactory {

	protected static HashMap<String, Node> propertyNodeMap = null;
	
	public static RGraph createGraph(RTable rt){
		RGraph g = new RGraph();
//		RNode root = g.addNode("root");
		
		if (propertyNodeMap == null)
			createPropertyNodeMap(rt.getQuery().getModel());
		for (int i =0; i < rt.getRowCount(); i++){
			RDFNode row[] = rt.getRow(i);
			int rl = row.length;
			for (int j = 0; j < rl; j++){
				if (isProperty(row[j]))
					continue;
				if (isValidNode(row[j], rt.getQuery().getNodeFilter())){
					RNode source = g.addNode(row[j]);
//					if (j == 0)
//						g.addEdge(root, source);
					int idx = j+1;
					for (int k = 0; k < rl; k++){
						if (idx >= rl)
							idx = 0;
						if (isProperty(row[idx])){
							idx++;
							continue;
						}
						if (isValidNode(row[idx], rt.getQuery().getNodeFilter())){
							RNode target = g.addNode(row[idx]);
							g.addEdge(source, target);
						}
						idx++;						
					}
				}
			}
		}
		
		Iterator<RNode> iter = g.getNodeIter();
		while(iter.hasNext()){
			RNode n = iter.next();
			if (n.getInEdge().isEmpty())
				System.out.println("SCHEI?E " + n.getName());
		}
		return g;
	}
	
	private static boolean isValidNode(RDFNode node, ArrayList<NodeFilter> arrayList) {
		for (int i = 0; i < arrayList.size(); i++)
			if (!isValidNode(node, arrayList.get(i)))
				return false;
		return true;
	}

	private static boolean isValidNode(RDFNode node, NodeFilter nodeFilter) {
		return nodeFilter.isValid(node);
	}

	private static boolean isProperty(RDFNode node) {
		if (node.isURIResource())
			return propertyNodeMap.containsKey(node.asNode().getURI());
		return false;
	}

	private static void createPropertyNodeMap(OWLModel model) {
		List list = model.listAllOntProperties().toList();
		propertyNodeMap = new HashMap<String, Node>();
		for (int i = 0; i < list.size(); i++){
			OntProperty prop =(OntProperty) list.get(i);
			String uri = prop.getURI();
			propertyNodeMap.put(uri, prop.asNode());
		}
	}
}
